<script setup>
import { ref, onMounted } from 'vue'
import { io } from 'socket.io-client'

const socket = io('http://localhost:3000') // 连接 WebSocket 服务器
const isMuted = ref(false)
const isVideoOn = ref(false)
const localVideo = ref(null)
const remoteVideos = ref([])
const chatMessages = ref([])
const roomId = ref('test-room')
const message = ref('')
const peers = {}
let localStream

// 加入房间
const joinRoom = async () => {
  localStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true })
  localVideo.value.srcObject = localStream
  socket.emit('join-room', roomId.value)
}

// 处理新用户加入
socket.on('new-user', async userId => {
  const peer = createPeer(userId)
  peers[userId] = peer
  const offer = await peer.createOffer()
  await peer.setLocalDescription(offer)
  socket.emit('offer', { roomId: roomId.value, offer, from: socket.id })
})

// 处理收到 offer
socket.on('offer', async ({ from, offer }) => {
  const peer = createPeer(from)
  peers[from] = peer
  await peer.setRemoteDescription(new RTCSessionDescription(offer))
  const answer = await peer.createAnswer()
  await peer.setLocalDescription(answer)
  socket.emit('answer', { roomId: roomId.value, answer, from: socket.id })
})

// 处理 answer
socket.on('answer', ({ from, answer }) => {
  peers[from].setRemoteDescription(new RTCSessionDescription(answer))
})

// 处理 ICE 候选
socket.on('candidate', ({ from, candidate }) => {
  peers[from].addIceCandidate(new RTCIceCandidate(candidate))
})

// 处理用户断开
socket.on('user-disconnected', userId => {
  if (peers[userId]) {
    peers[userId].close()
    delete peers[userId]
  }
})

// 处理聊天消息
socket.on('chat-message', ({ message, from }) => {
  chatMessages.value.push({ from, message })
})

// 发送聊天消息
const sendMessage = () => {
  socket.emit('chat-message', { roomId: roomId.value, message: message.value, from: socket.id })
  chatMessages.value.push({ from: 'Me', message: message.value })
  message.value = ''
}

// 创建 WebRTC 连接
function createPeer(userId) {
  const peer = new RTCPeerConnection({
    iceServers: [{ urls: 'stun:stun.l.google.com:19302' }],
  })

  peer.onicecandidate = event => {
    if (event.candidate) {
      socket.emit('candidate', { roomId: roomId.value, candidate: event.candidate, from: socket.id })
    }
  }

  peer.ontrack = event => {
    const videoElement = document.createElement('video')
    videoElement.srcObject = event.streams[0]
    videoElement.autoplay = true
    videoElement.controls = true
    remoteVideos.value.push(videoElement)
  }

  localStream.getTracks().forEach(track => peer.addTrack(track, localStream))
  return peer
}

// 控制麦克风
const toggleAudio = () => {
  isMuted.value = !isMuted.value
  localStream.getAudioTracks().forEach(track => (track.enabled = !isMuted.value))
}

// 控制摄像头
const toggleVideo = () => {
  isVideoOn.value = !isVideoOn.value
  localStream.getVideoTracks().forEach(track => (track.enabled = isVideoOn.value))
}
</script>

<template>
  <div>
    <h2>WebRTC 视频会议 & 聊天</h2>
    <div class="controls">
      <input v-model="roomId" placeholder="房间 ID" />
      <button @click="joinRoom">加入房间</button>
      <button @click="toggleAudio">{{ isMuted ? '🎙️ 开麦' : '🔇 关麦' }}</button>
      <button @click="toggleVideo">{{ isVideoOn ? '📷 关视频' : '📹 开视频' }}</button>
    </div>
    <div class="video-chat-container flex-wrap">
      <div class="video-container flex-wrap flex-3">
        <video class="main-video" ref="localVideo" autoplay muted></video>
        <div v-for="video in remoteVideos" :key="video.srcObject.id">
          <video :srcObject="video.srcObject" autoplay controls></video>
        </div>
      </div>

      <div class="chat-container flex-1">
        <div class="messages">
          <p v-for="(msg, index) in chatMessages" :key="index">
            <strong>{{ msg.from }}:</strong> {{ msg.message }}
          </p>
        </div>
        <div class="input-container flex">
          <input v-model="message" placeholder="输入消息" />
          <button @click="sendMessage">发送</button>
        </div>
      </div>
    </div>
  </div>
</template>

<style>
.flex-3 {
  flex: 3;
}
.flex-1 {
  flex: 1;
}
.flex{
    display: flex;
}
.flex-wrap {
  display: flex;
  flex-wrap: wrap;
}
</style>

<style>
.video-chat-container {
  width: 800px;
}
.video-container {
  width: 500px;
}

.main-video {
  width: 500px;
  aspect-ratio: 4/3;
  /* height: 500px; */
}
video {
  width: 100px;
  margin: 10px;
  border-radius: 10px;
  border: 2px solid #ccc;
}
.chat-container {
  width: 300px;
  margin-top: 10px;
  border-radius: 10px;
}
.messages {
  max-height: 200px;
  min-height: 100px;
  overflow-y: auto;
  border: 1px solid #ccc;
  padding: 10px;
  border-radius: 10px;
}
</style>
